package com.gitee.cnlongdb.server.connect.nettymission.handler;

import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import org.apache.commons.lang3.StringUtils;

import com.gitee.cnlongdb.basic.enums.sysnc.LongdbDataSyncEnms;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;

/**
 * 系统名称：NettyClientHandler.java
 * 模块名称：
 * 模块描述：netty-发送消息执行类
 * 功能列表：
 * 模块作者：ZOUYONG
 * 开发时间：2019年4月10日 下午10:11:27
 * 模块路径：com.gitee.cnlongdb.server.connect.nettymission.handler.NettyClientHandler
 * 更新记录：
 */
public class NettyClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

	private String message; // 需要发送到服务端的消息内容
	private Map<String, String> returnMap; // 服务端返回的对象
	private CountDownLatch doneSignal;	// 用于同步返回的线程对象值
	
	public NettyClientHandler() {}
	
	// 构造函数
	public NettyClientHandler(String message, Map<String, String> returnMap, CountDownLatch doneSignal) {
		this.message = message;
		this.returnMap = returnMap;
		this.doneSignal = doneSignal;
	}

	/**
	 * 向服务端发送数据
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		// System.out.println("客户端与服务端通道-开启：" + ctx.channel().localAddress() + "channelActive");
		if(StringUtils.isNotBlank(message)) {
			// System.out.println("客户端准备发送的数据包：" + message);
			ctx.writeAndFlush(Unpooled.copiedBuffer(message, CharsetUtil.UTF_8)); // 必须有flush
		}
	}

	/**
	 * channelInactive
	 * channel 通道 Inactive 不活跃的
	 * 当客户端主动断开服务端的链接后，这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
	 */
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		// System.out.println("客户端与服务端通道-关闭：" + ctx.channel().localAddress() + "channelInactive");
	}

	/**
	 * 功能描述：获取客户端返回的值
	 × 模块作者：ZOUYONG
	 × 开发时间：2019年4月30日 下午3:32:19
	 × 返回数据：void
	 */
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
		if(null == returnMap) {
			return;
		}
		StringBuffer message = new StringBuffer();
		String content = returnMap.get(LongdbDataSyncEnms.returnObject.name());
		if(StringUtils.isNotBlank(content)) {
			message.append(content);
		}
		ByteBuf buf = msg.readBytes(msg.readableBytes());
		String result = buf.toString(Charset.forName("utf-8")); // ByteBufUtil.hexDump(buf); // 密文
		message.append(result);
		boolean readEnd = message.toString().endsWith(LongdbDataSyncEnms.cnlongNettySplitUnpooled.name());
		if(StringUtils.isNotBlank(result)) {
			if(readEnd) {
				returnMap.put(LongdbDataSyncEnms.returnObject.name(), 
						message.toString().replace(LongdbDataSyncEnms.cnlongNettySplitUnpooled.name(), ""));
			} else {
				returnMap.put(LongdbDataSyncEnms.returnObject.name(), message.toString());
			}
		}
		returnMap.put(LongdbDataSyncEnms.returnCode.name(), LongdbDataSyncEnms.success.name());
		if(null != doneSignal && readEnd) {
			doneSignal.countDown();
		}
	}

	/**
	 * 功能描述：异常退出
	 * 模块作者：ZOUYONG
	 * 开发时间：2019年4月10日 下午9:51:42
	 * 更新记录：
	 */
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		ctx.close();
		// System.out.println("异常信息：\r\n" + cause.getMessage());
	}

}

